
#ifndef ROPUFU_MULTI_SENSOR_INFORMATION_INFORMATION_NONE_HPP_INCLUDED
#define ROPUFU_MULTI_SENSOR_INFORMATION_INFORMATION_NONE_HPP_INCLUDED

#include "../more_math.hpp"

#include <aftermath/template_math.hpp>

#include <array>
#include <cstdint>
#include <ostream>
#include <string>

namespace ropufu
{
    template <std::size_t t_count_streams>
    struct information_none_iterator
    {
        static const std::size_t count_streams = t_count_streams;
        typedef information_none_iterator<count_streams> type;

    private:
        std::array<bool, count_streams> m_position;

    public:
        explicit information_none_iterator(const std::array<bool, count_streams>& position)
            : m_position(position)
        {
        }

        static type first()
        {
            std::array<bool, count_streams> position;
            position.fill(false);
            position[0] = true;
            return type(position);
        }

        static type last()
        {
            std::array<bool, count_streams> position;
            position.fill(false);
            return type(position);
        }

        bool operator !=(const type& other) const
        {
            return this->m_position != other.m_position;
        }

        const std::array<bool, count_streams>& operator *() const
        {
            return this->m_position;
        }

        const type& operator ++()
        {
            for (std::size_t k = 0; k < count_streams; k++)
            {
                if (this->m_position[k]) this->m_position[k] = false;
                else
                {
                    this->m_position[k] = true;
                    break;
                }
            }
            return *this;
        }
    };

    template <std::size_t t_count_streams>
    struct information_none
    {
        static const std::size_t count_streams = t_count_streams;
        typedef information_none<count_streams> type;
        typedef information_none_iterator<count_streams> iterator_type;
        
        std::size_t cardinality() const
        {
            return aftermath::npow<2, count_streams>::value - 1;
        }

        iterator_type begin() const
        {
            return iterator_type::first();
        }

        iterator_type end() const
        {
            return iterator_type::last();
        }

        friend std::ostream& operator <<(std::ostream& os, const type&)
        {
            return os << "no_info";
        }
    };
}

#endif // ROPUFU_MULTI_SENSOR_INFORMATION_INFORMATION_NONE_HPP_INCLUDED
